<?php

namespace app\api\controller\v40;

use app\aliyun\controller\AliyunFilterWord;
use app\aliyun\controller\AliyunPhone;
use app\aliyun\controller\AliyunRtc;
use app\api\controller\v2\Auth;
use app\chat\LiveMessage;
use app\common\cachemodel\ZhunleUserAccount;
use app\common\cachemodel\zlcr3\Zlcr3ConsultAccount;
use app\common\cachemodel\zlcr3\Zlcr3ConsultChatInterceptRecord;
use app\common\cachemodel\zlcr3\Zlcr3ConsultChatRecord;
use app\common\cachemodel\zlcr3\Zlcr3ConsultChatRecordAstr;
use app\common\cachemodel\zlcr3\Zlcr3ConsultChatRecordDetails;
use app\common\cachemodel\zlcr3\Zlcr3ConsultChatRtcRecord;
use app\common\cachemodel\zlcr3\Zlcr3ConsultQuestion;
use app\common\cachemodel\ZlcrAstr;
use app\common\lib\Util;
use app\common\model\Recode;
use think\Db;
use think\Env;
use think\response\Json;

class UserConsultChat extends Auth
{
    /**
     * 获取 咨询对话记录 列表
     */
    public function getConsultChatIdList()
    {
        $zl6ConsultChatRecordModel = new Zlcr3ConsultChatRecord();
        $pageData = $zl6ConsultChatRecordModel->getListPage($this->user['id'], 'id', [], 0, 'desc', 0);

        $pageData['data'] = $zl6ConsultChatRecordModel->dataInit($pageData['data']);

        $pageData['data'] = $zl6ConsultChatRecordModel->pageDataResert($pageData['data']);

        $pageData['msg_num'] = (new Zlcr3ConsultChatRecord())->getUserUnreadAllNum($this->user['id']); // 未读消息数量

        return show(config('code.success'), '请求成功', $pageData);
    }

    /**
     * 删除 咨询对话记录
     */
    public function delConsultChatId()
    {
        $astrId = input('astr_id/d', 0);
        $consultChatIdModel = new Zlcr3ConsultChatRecord();
        $chatId = $consultChatIdModel->getChatIdByAstrId($this->user['id'], $astrId);

        if (!$chatId)
        {
            return show(config('code.success'), '会话记录已删除');
        }

        $res = $consultChatIdModel->delChat($this->user['id'], $astrId, $chatId);
        if ($res)
        {
            $consultChatIdModel->setUserUnreadChatIdMsgNum($this->user['id'], $chatId, 2, 0);

            return show(config('code.success'), '操作成功');
        }

        return show(config('code.error'), '服务异常，请稍后再试～');
    }

    /**
     * 获取 咨询对话 记录
     */
    public function getConsultChatRecord()
    {
        $astrId = input('astr_id/d', 0);
        $minId = input('min_id/d', 0);

        $consultChatIdModel = new Zlcr3ConsultChatRecord();
        $chatId = $consultChatIdModel->getChatIdByAstrId($this->user['id'], $astrId);

        if ($minId === 0 && $chatId)
        {
            $chatIdInfo = $consultChatIdModel->getInfoById($chatId, ['msg_num']);
            if ($chatIdInfo['msg_num'] > 0)
            {   // 更新 未读消息数量
                $consultChatIdModel->updateData($chatId, ['msg_num' => 0]);
                $consultChatIdModel->setUserUnreadChatIdMsgNum($this->user['id'], $chatId, 2, 0);
            }

            $zlcr3ConsultQuestionModel = new Zlcr3ConsultQuestion();
            $consultQuestionInfo = $zlcr3ConsultQuestionModel->getUserConsultQuestion($this->user['id']);

            if ($consultQuestionInfo && isset($consultQuestionInfo['extend']['send_astro']) && $consultQuestionInfo['extend']['send_astro'])
            {
                foreach ($consultQuestionInfo['extend']['send_astro'] as $key => $item)
                {
                    if ((int)$item['astr_id'] === $astrId && $item['answer_id'] && !$item['is_read'])
                    {   // 有答案了 并且 未读
                        $consultQuestionInfo['extend']['send_astro'][$key]['is_read'] = 1;
                        // 更新 阅读状态
                        $zlcr3ConsultQuestionModel->updateData($consultQuestionInfo['id'], $this->user['id'], ['extend' => json_encode($consultQuestionInfo['extend'], JSON_UNESCAPED_UNICODE)]);
                        break;
                    }
                }
            }
        }

        $consultChatRecordDetailsModel = new Zlcr3ConsultChatRecordDetails();
        $resData = $consultChatRecordDetailsModel->getPageDatas($chatId, 10, $minId);

        $astrInfo = (new ZlcrAstr())->getInfoById($astrId, ['nickname', 'avatar']);
        if (!$astrInfo)
        {
            return show(config('code.error'), '服务异常，请稍后再试～');
        }

        if ($resData['data'])
        {
            $resData['data'] = $consultChatRecordDetailsModel->userDataListResert($resData['data'], $astrInfo, $this->user, $delayComment);
        } else
        {
            if ($minId === 0)
            {
                $resData['data'][] = [
                    'id' => 0,
                    'type' => 2,
                    'time_des' => '',
                    'time' => 0,
                    'avatar' => $astrInfo['avatar'],
                    'msg_des' => '',
                    'tags' => [],
                    'consult_info' => null,
                    'content' => "Hi，很高兴为你服务！\r\n你可以和我聊聊你的疑惑，或者直接向我咨询。",
                    'content_type' => 1,
                    'btn_info' => null,
                ];
            }
        }


        // 占星师 昵称
        $resData['nickname'] = $astrInfo['nickname'];
        $numData = $consultChatRecordDetailsModel->getUserConsultAstrMsgNumByTodayEx($this->user['id'], $astrId);
        $resData['num'] = min($numData['total'], $numData['num'], $numData['max_num']);
        $resData['delay_comment'] = $delayComment ?? null;


        return show(config('code.success'), '请求成功', $resData);
    }

    /**
     * 发送 咨询 消息
     * @return Json
     * @throws \Exception
     */
    public function sendConsultMsg()
    {
        $astrId = input('astr_id/d', 0);
        $type = input('type/d', 0);
        $content = input('content/s', '');

        if (!in_array($type, [1, 2], true))
        {
            return show(config('code.error'), '请求异常，请稍后再试～');
        }

        if (Util::commentCheck($this->user['id'], ['action' => 'sendConsultMsg', 'type' => $type, 'astr_id' => $astrId, 'content' => $content], 5))
        {
            return show(config('code.error'), '操作频繁，请稍后再试～');
        }
        // 当前 $astrId 是 咨询师ID
        if (!in_array($astrId, (new ZlcrAstr())->getConsultAstroIds(), true))
        {
            return show(config('code.error'), '服务异常，咨询师不存在～');
        }
        $consultChatRecordDetailsModel = new Zlcr3ConsultChatRecordDetails();
        $numData = $consultChatRecordDetailsModel->getUserConsultAstrMsgNumByTodayEx($this->user['id'], $astrId);
        $sendNum = min($numData['total'], $numData['num'], $numData['max_num']);
        if ($sendNum <= 0)
        {
            return show(config('code.error'), '机会已用尽，发送失败～');
        }
        $consultChatIdModel = new Zlcr3ConsultChatRecord();
        $chatId = $consultChatIdModel->getChatIdByAstrId($this->user['id'], $astrId);

        $nowTimw = $this->request->time();
        if (!$chatId)
        {
            $insertData = [
                'uid' => $this->user['id'],
                'astr_id' => $astrId,
                'last_chat_detail_id' => 0,
                'last_chat_detail_time' => 0,
                'create_time' => $nowTimw,
            ];
            // 创建新的会话
            $chatId = $consultChatIdModel->SaveData($insertData);
        }

        //阿里云内容审查
        if ($type === 1)
        {
            $res = AliyunFilterWord::checkText($content, 'voice_mic');
        } else
        {
            $oss = Env::get('host.photo');
            $res = AliyunFilterWord::checkImg(1, $oss . $content, 'voice_mic');
            if ($res['status'] === true)
            {
                $res = [];
            }
        }
        if ($res)
        {
            if ($res['level'] === 'review')
            {
                $interceptTips = $consultChatRecordDetailsModel->interceptTips;
                (new Zlcr3ConsultChatInterceptRecord())->saveData([
                    'type' => 2,
                    'level' => 1,
                    'content_type' => $type,
                    'chat_id' => $chatId,
                    'user_id' => $this->user['id'],
                    'content' => $content,
                    'reason' => $res['text'],
                    'create_time' => $this->request->time()
                ]);
            } elseif ($res['level'] === 'block')
            {
                (new Zlcr3ConsultChatInterceptRecord())->saveData([
                    'type' => 2,
                    'level' => 2,
                    'content_type' => $type,
                    'chat_id' => $chatId,
                    'user_id' => $this->user['id'],
                    'content' => $content,
                    'reason' => $res['text'],
                    'create_time' => $this->request->time()
                ]);
                return show(430, '发送失败，你所发送的内容中包含敏感信息。 注意不要泄露自己的联系方式和个人信息，以防上当受骗，平台将对你的个人隐私严格保密 。');
            }
        }
        $consultMsgData = [
            'chat_id' => $chatId,
            'uid' => $this->user['id'],
            'astr_id' => $astrId,
            'type' => 2,    //  1=>APP消息 2=>用户发送消息
            'title' => '',
            'content' => $content, // 提问问题
            'data_type' => $type,   // 1=>普通消息  2=>图片  3=>语音咨询消息
            'extend' => ['intercept_tips' => isset($interceptTips) ? $res['text'] : ''],  //  语音咨询消息 ｜ 图片信息 | 内容拦截信息
            'pid' => 0, // 待更新
            'create_time' => $nowTimw,
        ];

        $resData = $consultChatRecordDetailsModel->SaveData($chatId, $consultMsgData);

        if ($resData)
        {   // 更新用户端 最后咨询信息
            $consultChatIdModel->updateData($chatId, [
                'last_chat_detail_id' => $resData['id'],
                'last_chat_detail_time' => $nowTimw,
            ]);
            // 更新咨询师端 最后咨询信息
            $zlcr3ConsultChatRecordAstrModel = new Zlcr3ConsultChatRecordAstr();
            $zlcr3ConsultChatRecordAstrModel->userSendUpdate($this->user['id'], $astrId, [
                'last_chat_detail_id' => $resData['id'],
                'last_chat_detail_time' => $nowTimw,
                'user_last_msg_time' => $nowTimw,
                'unread_num' => Db::raw('unread_num + 1'),
                'question_num' => Db::raw('question_num + 1'),
                'delay_num' => Db::raw('delay_num + 1'),
            ]);

            $resData1 = current($consultChatRecordDetailsModel->userDataListResert([$resData], [], $this->user));
            // 判断咨询师是否在线
            if (LiveMessage::getUserIsOnline(2, $astrId))
            {   // 向 咨询师发送消息
                $astrData2 = current($consultChatRecordDetailsModel->astrDataListResert([$resData], [], $this->user));
                LiveMessage::sendMsg(LiveMessage::who(LiveMessage::WHO_TYPE_ASTRO, 0, $astrId), LiveMessage::MSG_TYPE_POP_CONSULT_MSG, [
                    'msg_type' => 2,
                    'uid' => $this->user['id'],
                    'msg_data' => $astrData2
                ]);
            }
            // 发送 咨询问题 数量增加
            $consultChatRecordDetailsModel->setUserConsultMsgAstrNumByTodayInc($this->user['id'], $astrId);
            $resData1['time_des'] = '';
            $resData1['intercept_tips'] = $interceptTips ?? '';
            return show(config('code.success'), '请求成功', $resData1);
        }

        return show(config('code.error'), '服务异常，请稍后再试～');
    }

    /**
     * 发送 咨询 问题
     * @return Json
     * @throws \Exception
     */
    public function sendConsultQuestion()
    {
        $question = trim(input('question/s', ''));

        if (empty($question))
        {
            return show(config('code.error'), '提交咨询问题不能为空～');
        }

        if (mb_strlen($question) > 100)
        {
            return show(config('code.error'), '提交咨询问题最多100字～');
        }

        // 判断当前是否 已经 提交过了
        $zlcr3ConsultQuestionModel = new Zlcr3ConsultQuestion();
        $consultQuestionInfo = $zlcr3ConsultQuestionModel->getUserConsultQuestion($this->user['id']);
        if ($consultQuestionInfo)
        {
            $t = 86400 - ($this->request->time() - $consultQuestionInfo['create_time']);
            if ($t > 3600)
            {
                $t = (int)(round($t / 3600)) . '小时';
            } else
            {
                $t = ceil(($t % 3600) / 60) . '分钟';
            }

            return show(config('code.error'), $t . '后才能再次提交咨询问题～');
        }

        //内容检测
        $res = AliyunFilterWord::checkText($question, 'voice_mic');
        if ($res)
        {
            if ($res['level'] === 'review')
            {
                $interceptTips = (new Zlcr3ConsultChatRecordDetails())->interceptTips;
            } elseif ($res['level'] === 'block')
            {
                return show(430, '发送失败，你所发送的内容中包含敏感信息。 注意不要泄露自己的联系方式和个人信息，以防上当受骗，平台将对你的个人隐私严格保密 。');
            }
        }

        $data = [
            'uid' => $this->user['id'],
            'content' => $question,
            'extend' => [
                'intercept_tips' => isset($interceptTips) ? $res['text'] : '',
                'send_astro' => []
            ],
            'create_time' => $this->request->time()
        ];

        $id = $zlcr3ConsultQuestionModel->saveData($data);
        $data['id'] = $id;
        // 添加到队列
        Util::queuePush('send_consult_question', ['uid' => $this->user['id'], 'id' => $id], 10);

        $resData = $zlcr3ConsultQuestionModel->resetConsultQuestion($data);

        return show(config('code.success'), '请求成功', $resData);
    }

    /**
     * 发起 RTC连麦 交互请求
     * @return Json
     * @throws \Exception
     */
    public function requestRtcInteraction()
    {
        $astrId = input('astr_id/d', 0);

        $zlcrAstrModel = new ZlcrAstr();
        if (!in_array($astrId, $zlcrAstrModel->getConsultAstroIds(), true))
        {
            return show(config('code.error'), '服务异常，咨询师不存在～');
        }

        if (Util::commentCheck($this->user['id'], ['action' => 'requestRtcInteraction', 'astr_id' => $astrId], 5))
        {
            return show(config('code.error'), '操作频繁，请稍后再试～');
        }
        // 获取当前用户 咨询状态
        $zlcr3ConsultChatRtcRecordModel = new Zlcr3ConsultChatRtcRecord();
        $userNowConsultRtcInfo = $zlcr3ConsultChatRtcRecordModel->getNowRtcDataByCache(1, $this->user['id']);
        if ($userNowConsultRtcInfo)
        {   // 用户正在连麦中
            return show(config('code.error'), '当前正在连线中，不可重复连线～');
        }
        // 咨询师营业状态判断 不是ws在线状态
        $consultAccountInfo = (new Zlcr3ConsultAccount())->getInfoById($astrId);
        if ($consultAccountInfo['status'] !== 1)
        {   // 咨询师休息 了
            return show(config('code.error'), '咨询师暂时不在，稍侯再来吧~');
        }
        // 获取当前咨询师 咨询状态
        $astrNowConsultRtcInfo = $zlcr3ConsultChatRtcRecordModel->getNowRtcDataByCache(2, $astrId);
        if ($astrNowConsultRtcInfo)
        {   // 咨询师 当前正在 连麦中 或者 已经有连麦请求
            $extend = [
                'rtc_data' => [
                    'rtc_id' => 0,
                    'status' => 5,  //【rtc_id=0该字段数据生效】 1=>申请中待接听  2=>咨询师未响应  3=>咨询师拒绝  4=>连线已取消 5=>咨询师忙线中
                ]
            ];
            $isRtc = false;
        } else
        {
            $extend = [
                'rtc_data' => [
                    'rtc_id' => 0,
                    'status' => 1,  //【rtc_id=0该字段数据生效】 1=>申请中待接听  2=>咨询师未响应  3=>咨询师拒绝  4=>连线已取消 5=>咨询师忙线中
                ]
            ];
            $isRtc = true;
        }
        $consultChatIdModel = new Zlcr3ConsultChatRecord();
        $chatId = $consultChatIdModel->getChatIdByAstrId($this->user['id'], $astrId);
        $nowTimw = $this->request->time();
        if (!$chatId)
        {
            $insertData = [
                'uid' => $this->user['id'],
                'astr_id' => $astrId,
                'last_chat_detail_id' => 0,
                'last_chat_detail_time' => 0,
                'create_time' => $nowTimw,
            ];
            // 创建新的会话
            $chatId = $consultChatIdModel->SaveData($insertData);
        }

        $consultMsgData = [
            'chat_id' => $chatId,
            'uid' => $this->user['id'],
            'astr_id' => $astrId,
            'type' => 2,    //  1=>APP消息 2=>用户发送消息
            'title' => '',
            'content' => '', // 提问问题
            'data_type' => 3,   // 1=>普通消息  2=>图片  3=>语音咨询消息
            'extend' => $extend,  //  语音咨询消息 ｜ 图片信息
            'pid' => 0, // 待更新
            'create_time' => $nowTimw,
        ];

        $consultChatRecordDetailsModel = new Zlcr3ConsultChatRecordDetails();
        $resData = $consultChatRecordDetailsModel->SaveData($chatId, $consultMsgData);
        if ($resData)
        {
            $consultChatIdModel->updateData($chatId, [
                'last_chat_detail_id' => $resData['id'],
                'last_chat_detail_time' => $nowTimw,
            ]);
            // 更新咨询师端 最后咨询信息
            (new Zlcr3ConsultChatRecordAstr())->userSendUpdate($this->user['id'], $astrId, [
                'last_chat_detail_id' => $resData['id'],
                'last_chat_detail_time' => $nowTimw,
                'unread_num' => Db::raw('unread_num + 1'),
                'call_num' => Db::raw('call_num + 1'),
            ]);

            $resData2 = current($consultChatRecordDetailsModel->userDataListResert([$resData], [], $this->user));

            if ($isRtc)
            {   // 更新用户端 最后咨询信息
                $astrInfo = $zlcrAstrModel->getInfoById($astrId, ['avatar', 'nickname', 'tel']);
                $userNowConsultRtcInfo = [
                    'id' => 0, // 连麦ID    ID==0 为邀请连麦  否则为主播接受连麦
                    'rtc_sign' => uniqid('', false),
                    'astr_id' => $astrId,
                    'nickname' => $astrInfo['nickname'] ?? '',
                    'avatar' => $astrInfo['avatar'] ?? '',
                    'status' => 1,  // 当前连麦状态 1=>等待咨询师接受 2=>咨询师接受开始连麦中 3=>连麦成功 连麦中
                    'request_time' => $this->request->time(),   // 邀请咨询师连麦时间
                    'chat_id' => $resData['id']
                ];
                $zlcr3ConsultChatRtcRecordModel->saveNowRtcDataToCache(1, $this->user['id'], $userNowConsultRtcInfo, false);
                $astrNowConsultRtcInfo = [
                    'id' => 0, // 连麦ID    ID==0 为邀请连麦  否则为主播接受连麦
                    'rtc_sign' => $userNowConsultRtcInfo['rtc_sign'],
                    'uid' => $this->user['id'],
                    'nickname' => $this->user['nickname'] ?? '',
                    'avatar' => $this->user['avatar'] ?? '',
                    'uen' => $this->user['uen'] ?? '',
                    'status' => 1,  // 当前连麦状态 1=>等待咨询师接受 2=>咨询师接受开始连麦中 3=>连麦成功 连麦中
                    'request_time' => $this->request->time(),   // 邀请咨询师连麦时间
                    'chat_id' => $resData['id']
                ];
                $zlcr3ConsultChatRtcRecordModel->saveNowRtcDataToCache(2, $astrId, $astrNowConsultRtcInfo, false);

                // 判断咨询师是否在线
                if (LiveMessage::getUserIsOnline(2, $astrId))
                {   // 在线
                    $astrData = current($consultChatRecordDetailsModel->astrDataListResert([$resData], [], $this->user));
                    LiveMessage::sendMsg(LiveMessage::who(LiveMessage::WHO_TYPE_ASTRO, 0, $astrId), LiveMessage::MSG_TYPE_POP_CONSULT_MSG, [
                        'msg_type' => 2,
                        'uid' => $this->user['id'],
                        'msg_data' => $astrData
                    ]);

                    $voiceCallData = [
                        'chat_id' => $resData['id'],
                        'uid' => $this->user['id'],
                        'avatar' => $this->user['avatar'],
                        'nickname' => $this->user['nickname'],
                        'status' => 1
                    ];
                    LiveMessage::sendMsg(LiveMessage::who(LiveMessage::WHO_TYPE_ASTRO, 0, $astrId), LiveMessage::MSG_TYPE_POP_VOICE_CONSULT_CALL, $voiceCallData);
                } else
                {   // 咨询师ws不在线
                    AliyunPhone::singleCallByTts($astrInfo['tel'], 'TTS_282195080');
                }
                // 2分钟后 判断状态是否还是待接听 状态 如果是待接听状态 则取消连线
                Util::queuePush('rtc_consult_accept_check', ['id' => $resData['id']], 120);
            }
            $resData2['time_des'] = '';
            return show(config('code.success'), '请求成功', $resData2);
        }

        return show(config('code.error'), '服务异常，请稍后再试～');
    }

    /**
     * 挂断连线｜取消连线（未接听）
     * @return Json
     * @throws \Exception
     */
    public function rtcCancel()
    {
        $chatDetailid = input('id/d', 0);
        $type = input('type/d', 0);
        $reason = input('reason/s', '');

        if (!$chatDetailid)
        {
            return show(config('code.error'), '请求异常，请稍后再试～');
        }

        if (Util::commentCheck($this->user['id'], ['action' => 'rtcCancel', 'id' => $chatDetailid, 'type' => $type, 'reason' => $reason], 5))
        {
            return show(config('code.error'), '操作频繁，请稍后再试～');
        }

        // 获取当前用户 咨询状态
        $zlcr3ConsultChatRtcRecordModel = new Zlcr3ConsultChatRtcRecord();
        $consultChatRecordDetailsModel = new Zlcr3ConsultChatRecordDetails();
        $userNowConsultRtcInfo = $zlcr3ConsultChatRtcRecordModel->getNowRtcDataByCache(1, $this->user['id']);
        $astrWsIsOnline = false;
        if ($userNowConsultRtcInfo)
        {   // 用户正在连麦中
            if ((int)$userNowConsultRtcInfo['chat_id'] === $chatDetailid)
            {   // 删除当前连麦 信息
                $astrId = (int)$userNowConsultRtcInfo['astr_id'];
                // 更新当前连麦信息
                $astrNowConsultRtcInfo = $zlcr3ConsultChatRtcRecordModel->getNowRtcDataByCache(2, $astrId);
                if ((int)$astrNowConsultRtcInfo['chat_id'] === $chatDetailid)
                {   // 当前连麦数据正确
                    if (LiveMessage::getUserIsOnline(2, $astrId))
                    {   //  隐藏 电话提醒
                        $astrWsIsOnline = true;
                        $voiceCallData = [
                            'chat_id' => $chatDetailid,
                            'avatar' => $this->user['avatar'],
                            'nickname' => $this->user['nickname'],
                            'status' => 0
                        ];
                        LiveMessage::sendMsg(LiveMessage::who(LiveMessage::WHO_TYPE_ASTRO, 0, $astrId), LiveMessage::MSG_TYPE_POP_VOICE_CONSULT_CALL, $voiceCallData);
                    }
                }
                $chatDetail = $consultChatRecordDetailsModel->getInfoById($chatDetailid);

                if ($userNowConsultRtcInfo['id'])
                {   // 连线成功
                    $data = $zlcr3ConsultChatRtcRecordModel->rtcConsultHangUp($chatDetail, $reason, 1, 1);
                    if ($data['status'])
                    {   // 删除 频道订阅 与 当前RTC房间
                        (new AliyunRtc())->rmEventSubAndDelRtcChannel('consult_' . $userNowConsultRtcInfo['id']);
                        return show(config('code.success'), '请求成功', $data['data']);
                    }

                    $zlcr3ConsultChatRtcRecordModel->delNowRtcDataByCache(1, $this->user['id']); // 删除当前连麦信息
                    return show(config('code.error'), $data['msg']);
                }

                // 未连线成功
                $zlcr3ConsultChatRtcRecordModel->delNowRtcDataByCache(1, $this->user['id']);
                if ((int)$astrNowConsultRtcInfo['uid'] === $this->user['id'])
                {
                    $zlcr3ConsultChatRtcRecordModel->delNowRtcDataByCache(2, $astrId);
                }
                $chatDetail['extend']['rtc_data']['status'] = 4;  //【rtc_id=0该字段数据生效】 1=>申请中待接听  2=>咨询师未响应  3=>咨询师拒绝  4=>连线已取消 5=>咨询师忙线中
                // 更新数据
                $consultChatRecordDetailsModel->UpdateData($chatDetailid, ['extend' => $chatDetail['extend']]);

                $resData2 = current($consultChatRecordDetailsModel->userDataListResert([$chatDetail], [], $this->user));

                $zlcr3ConsultChatRecordAstrModel = new Zlcr3ConsultChatRecordAstr();
                $userChatId = $zlcr3ConsultChatRecordAstrModel->getIdByAstrIdAndUid($astrId, $this->user['id']);
                if ($userChatId)
                {
                    $userChatInfo = $zlcr3ConsultChatRecordAstrModel->getInfoById($userChatId, 'unread_num');
                    if ($userChatInfo['unread_num'] === 0)
                    {
                        // 更新咨询师端 最后咨询信息
                        (new Zlcr3ConsultChatRecordAstr())->userSendUpdate($this->user['id'], $astrId, [
                            'unread_num' => Db::raw('unread_num + 1'),
                        ]);
                    }
                }

                if ($astrWsIsOnline)
                {
                    $astrData = current($consultChatRecordDetailsModel->astrDataListResert([$chatDetail], [], $this->user));

                    LiveMessage::sendMsg(LiveMessage::who(LiveMessage::WHO_TYPE_ASTRO, 0, $astrId), LiveMessage::MSG_TYPE_POP_CONSULT_MSG, [
                        'msg_type' => 2,
                        'uid' => $this->user['id'],
                        'msg_data' => $astrData
                    ]);
                }

                return show(config('code.success'), '取消成功', $resData2);

            }

            return show(config('code.error'), '语音连线咨询状态异常，请稍后再试～');
        }

        return show(config('code.error'), '语音连线咨询状态异常，请稍后再试～');
    }

    /**
     * 获取 故障挂断 原因
     * @return Json
     */
    public function getCancelReason()
    {
        $data = [
            [
                'id' => 1,
                'name' => '听不见主播声音',
            ], [
                'id' => 2,
                'name' => '主播听不见我的声音',
            ],
            [
                'id' => 3,
                'name' => '主播有杂音',
            ],
            [
                'id' => 4,
                'name' => '我的麦有杂音',
            ],
        ];

        return show(config('code.success'), '请求成功', $data);
    }

    /**
     * 获取连线咨询状态
     * @return Json
     * @throws \Exception
     */
    public function getRtcConsultStatusInfo()
    {
        $astrId = input('astr_id/d', 0);
        $chatDetailId = input('id/d', 0);

        $zlcrAstrModel = new ZlcrAstr();
        $zlcr3ConsultAccountModel = new Zlcr3ConsultAccount();
        $zlcr3ConsultChatRtcRecordModel = new Zlcr3ConsultChatRtcRecord();
        $zlcr3ConsultChatRecordDetailsModel = new Zlcr3ConsultChatRecordDetails();

        $chatDetail = null;
        if ($chatDetailId)
        {
            $chatDetail = $zlcr3ConsultChatRecordDetailsModel->getInfoById($chatDetailId);
            if (!$chatDetail)
            {
                return show(config('code.error'), '请求异常，咨询信息不存在～');
            }

            $userNowConsultRtcInfo = $zlcr3ConsultChatRtcRecordModel->getNowRtcDataByCache(1, $this->user['id']);
            if ($userNowConsultRtcInfo && (int)$userNowConsultRtcInfo['chat_id'] === $chatDetailId && $userNowConsultRtcInfo['status'] < 3)
            {
                $chatDetail = null;
            }
        } else
        {
            $consultAstrIds = ($zlcrAstrModel)->getConsultAstroIds(0);
            if (!in_array($astrId, $consultAstrIds, true))
            {
                return show(config('code.error'), '服务异常，咨询师不存在');
            }
            // 获取当前 连线信息
            $userNowConsultRtcInfo = $zlcr3ConsultChatRtcRecordModel->getNowRtcDataByCache(1, $this->user['id']);
            if ($userNowConsultRtcInfo)
            {   // 用户当前连线信息
                if ((int)$userNowConsultRtcInfo['astr_id'] !== $astrId)
                {
                    return show(config('code.error'), '你当前正在连线中，不可重复连线。');
                }
                if ((int)$userNowConsultRtcInfo['status'] === 3)
                {    // 当前连麦状态 1=>等待咨询师接受 2=>咨询师接受开始连麦中 3=>连麦成功 连麦中
                    // 当前正在连麦中
                    $chatDetail = $zlcr3ConsultChatRecordDetailsModel->getInfoById($userNowConsultRtcInfo['chat_id']);
                }
                $chatDetailId = (int)$userNowConsultRtcInfo['chat_id'];
            }
        }

        if ($chatDetail)
        {
            $rtcId = $chatDetail['extend']['rtc_data']['rtc_id'] ?? 0;
            if (!$rtcId)
            {
                return show(config('code.error'), '服务异常，请稍后再试～');
            }
            $avatar = $userNowConsultRtcInfo['avatar'] ?? '';
            $nickname = $userNowConsultRtcInfo['nickname'] ?? '';
            if (!$userNowConsultRtcInfo)
            {
                $astrInfo = (new ZlcrAstr())->getInfoById($astrId, ['avatar', 'nickname']);
                $avatar = $astrInfo['avatar'];
                $nickname = $astrInfo['nickname'];
            }
            // 获取当前 连线信息
            $rtcInfo = $zlcr3ConsultChatRtcRecordModel->getInfoById($rtcId);
            switch ($rtcInfo['status'])
            {   //  2=>连接中  3=>连麦中 4=>连麦结束 5=>故障挂断 6=>取消连麦（连接中挂断）
                case 3: // 3=>连麦中
                    $astrNowConsultRtcInfo = $zlcr3ConsultChatRtcRecordModel->getNowRtcDataByCache(2, $astrId);
                    $user_coin = (new ZhunleUserAccount())->getUserCoinFromCache($this->user['id']);  // 账户信息
                    $coinNum = (int)($user_coin['balance'] ?? 0);// 准币余额
                    $resData = [
                        'status' => 21,
                        'duration' => $this->request->time() - $rtcInfo['start_time'],
                        'test_duration' => $rtcInfo['test_duration'],
                        'user_coin' => $coinNum,                // 用户剩余准币数量
                        'used_coin' => $rtcInfo['coin'],        // 用户已经使用准币数量
                        'price_coin' => $rtcInfo['unit_price'], // 单价
                        'details' => $zlcr3ConsultChatRtcRecordModel->resetRtcConsultStatusData($astrNowConsultRtcInfo)
                    ];
                    break;
                case 4: // 4=>连麦结束
                case 5: // 5=>故障挂断
                    $resData = [
                        'status' => 31,
                        'duration' => $rtcInfo['duration'],
                        'coin' => $rtcInfo['coin'],
                        'avatar' => $avatar,
                        'name' => $nickname,
                        'id' => $chatDetailId,
                    ];
                    break;
                case 6:
                    $resData = [
                        'status' => 31,
                        'duration' => 0,
                        'coin' => 0,
                        'avatar' => $avatar,
                        'name' => $nickname,
                        'id' => $chatDetailId,
                    ];
                    break;
                default:
                    return show(config('code.error'), '服务异常，请稍后再试～');
            }
        } else
        {
            // 当前 没有连麦
            $astrInfo = $zlcrAstrModel->getInfoById($astrId);
            $consultAccount = $zlcr3ConsultAccountModel->getInfoById($astrId);

            if (isset($userNowConsultRtcInfo) && $userNowConsultRtcInfo)
            {   // 当前正在连线
                if ((int)$userNowConsultRtcInfo['status'] === 1)
                {   //  1=>等待咨询师接受
                    $status = 12;
                    $btnText = '等待咨询师响应';
                } else
                {   //  2=>咨询师接受开始连麦中
                    $status = 13;
                    $btnText = '连接中';
                }
            } else
            {   // 当前没有连线信息
                if ($consultAccount['status'] === 1)
                {   // 在线
                    $status = 0;
                    $btnText = '申请连线咨询（免费试麦1分钟）';
                } else
                {   // 休息
                    $status = 1;
                    $btnText = '咨询师休息中，请稍后再来';
                }
            }
            $tip = '';
            if ($consultAccount['service_duration'] > 0)
            {
                $t = ceil($consultAccount['service_duration'] / 60);
                $tip .= '服务' . ($t > 200 ? '200+' : $t) . '分钟';
            }
            if ($consultAccount['recommended_nums'] > 0)
            {
                $tip .= "·{$consultAccount['recommended_nums']}次被推荐";
            }

            $user_coin = (new ZhunleUserAccount())->getUserCoinFromCache($this->user['id']);  // 账户信息
            $coinNum = (int)($user_coin['balance'] ?? 0);// 准币余额
            $coinPwdStatus = (isset($user_coin['password']) && $user_coin['password']) ? 1 : 0;  // 是否设置了支付密码

            $resData = [
                'status' => $status,
                'avatar' => $astrInfo['avatar'],
                'name' => $astrInfo['nickname'],
                'tags_icon' => $zlcr3ConsultAccountModel->getTagsIcon($consultAccount['tids']),
                'tags' => $zlcr3ConsultAccountModel->getTags($consultAccount['tags']),
                'user_coin' => $coinNum,
                'is_set_password' => $coinPwdStatus,
                'price_coin' => $consultAccount['price'],
                'tip' => $tip,
                'notice' => "连麦开始1分钟内是免费试麦准备时间，如果出现声音问题请及时申请故障挂断，调试后重试。\r\n请保证网络正常，以免因网络问题影响你的咨询体验。\r\n连麦咨询不支持退款，请谨慎购买，理性消费：为保证咨询服务的完整性，请尽量保证准币余额充足。",
                'des' => $astrInfo['extend']['work_intro'] ?? '',    // 营业介绍
                'btn_text' => $btnText,
                'id' => $chatDetailId ?? 0
            ];
        }

        return show(config('code.success'), '请求成功', $resData);
    }

    /**
     * 更新连线咨询信息
     * @return Json
     * @throws \Exception
     */
    public function updateRtcConsultShareData()
    {
        $chatDetailId = input('id/d', 0);
        $recodeDatas = input('recode_datas/s', '');
        $diceDatas = input('dice_datas/s', '');
        $tarotDatas = input('tarot_datas/s', '');
        $type = input('type/d', 0);
        if (!$chatDetailId || !in_array($type, [1, 2, 3], true))
        {
            return show(config('code.error'), '请求异常，操作失败');
        }

        $zlcr3ConsultChatRecordDetailsModel = new Zlcr3ConsultChatRecordDetails();
        $zlcr3ConsultChatRtcRecordModel = new Zlcr3ConsultChatRtcRecord();

        $chatDetail = $zlcr3ConsultChatRecordDetailsModel->getInfoById($chatDetailId);

        if (!$chatDetail || $chatDetail['uid'] !== $this->user['id'])
        {
            return show(config('code.error'), '服务异常，当前咨询不存在～');
        }
        $astrId = $chatDetail['astr_id'];
        $astrNowConsultRtcInfo = $zlcr3ConsultChatRtcRecordModel->getNowRtcDataByCache(2, $astrId);

        if (!$astrNowConsultRtcInfo || (int)$astrNowConsultRtcInfo['chat_id'] !== $chatDetailId)
        {
            return show(config('code.error'), '服务异常，请稍后再试～');
        }

        $updateData = [];
        switch ($type)  // //  1=>星盘 2=>骰子 3=>塔罗
        {
            case 1: //  1=>星盘
                $recodeDatasArr = $recodeDatas ? json_decode($recodeDatas, true) : [];
                if (count($recodeDatasArr) > 10)
                {
                    return show(config('code.error'), '请求异常，最多选择10个档案～');
                }
                $resData = [];
                $sexTxt = [
                    1 => '男',
                    2 => '女'
                ];
                $recodeModel = new Recode();
                $utilModel = new Util();
                foreach ($recodeDatasArr as $rid)
                {
                    $recode = $recodeModel->getRecode(['id' => $rid]);
                    if (!$recode || $recode['uid'] != $this->user['id'])
                    {
                        return show(config('code.error'), '服务异常,档案信息异常～');
                    }
                    // 周岁
                    $age = Util::getAgeByBirth($recode['year'], $recode['month'], $recode['day'], 2);
                    $sex = $sexTxt[$recode['type']] ?? '未知';
                    $userDes = '日' . $utilModel->recodeAstroShorthand($recode['sun']) . '月' . $utilModel->recodeAstroShorthand($recode['moon']) . '升' . $utilModel->recodeAstroShorthand($recode['asc']);

                    $resData[] = [
                        'rid' => (int)$rid,
                        'name' => $recode['name'],
                        'avatar' => $recode['avatar'],
                        'comments' => $recode['comments'],
                        'user_des' => "{$sex}·{$age}周岁 {$userDes}"
                    ];
                }

                $updateData['recode_datas'] = $resData;
                break;
            case 2: //  2=>骰子
                $diceDatasArr = $diceDatas ? json_decode($diceDatas, true) : [];
                if (count($diceDatasArr) > 10)
                {
                    return show(config('code.error'), '请求异常，最多投10次结果～');
                }
                $resData = [];
                $planetArr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 16];// 行星id随机数种子
                foreach ($diceDatasArr as $diceData)
                {
                    if (!isset($diceData['planet'], $diceData['sign'], $diceData['house']))
                    {
                        return show(config('code.error'), '操作失败,骰子信息异常～');
                    }
                    if (!in_array($diceData['planet'], $planetArr, true) || $diceData['sign'] < 1 || $diceData['sign'] > 12 || $diceData['house'] < 1 || $diceData['house'] > 12)
                    {
                        return show(config('code.error'), '操作失败,骰子信息异常～');
                    }
                    $resData[] = $diceData;
                }
                $updateData['dice_datas'] = $resData;
                break;
            case 3: //  3=>塔罗
                $tarotDatasArr = $tarotDatas ? json_decode($tarotDatas, true) : [];
                if (count($tarotDatasArr) > 10)
                {
                    return show(config('code.error'), '请求异常，最多抽牌10轮～');
                }
                $resData = [];
                foreach ($tarotDatasArr as $tarotData)
                {
                    $resData1 = [];
                    foreach ($tarotData as $k => $tarotItem)
                    {
                        if ($tarotItem['card_id'] < 1 || $tarotItem['card_id'] > 78 || !in_array((int)$tarotItem['direction'], [1, 2], true))
                        {
                            return show(config('code.error'), '操作失败,更新信息异常～');
                        }
                        if (isset($tarotItem['index']))
                        {
                            $index = $tarotItem['index'];
                        } else
                        {
                            $index = $k + 1;
                        }
                        $resData1[] = [
                            'card_id' => $tarotItem['card_id'],
                            'direction' => $tarotItem['direction'],
                            'index' => $index,
                        ];
                    }

                    $resData[] = $resData1;
                }

                $updateData['tarot_datas'] = $resData;
                break;
        }

        $zlcr3ConsultChatRtcRecordModel->saveNowRtcDataToCache(2, $astrId, $updateData, true);

        // 向 咨询师 发送消息
        $consultDetailRefresh = [
            'target' => 'local',
            'link' => "alert_consult_question?id={$chatDetailId}&need_auth=2",
            'force_open' => 1,
        ];
        LiveMessage::sendMsg(LiveMessage::who(LiveMessage::WHO_TYPE_ASTRO, 0, $astrId), LiveMessage::MSG_TYPE_POP_CONSULT_DETAIL_REFRESH, $consultDetailRefresh);

        return show(config('code.success'), '请求成功');
    }

    /**
     * 咨询消息已读
     * @return Json
     * @throws \Exception
     */
    public function consultChatMsgRead()
    {
        $astrId = input('astr_id/d', 0);
        if (!$astrId)
        {
            return show(config('code.error'), '请求异常，请稍后再试～');
        }
        $consultChatIdModel = new Zlcr3ConsultChatRecord();
        $chatId = $consultChatIdModel->getChatIdByAstrId($this->user['id'], $astrId);
        if ($chatId)
        {
            $consultChatIdModel->updateData($chatId, ['msg_num' => 0]);
            $consultChatIdModel->setUserUnreadChatIdMsgNum($this->user['id'], $chatId, 2, 0);
        }

        return show(config('code.success'), '请求成功');
    }
}
